
import { NavItem, RouteItem } from '../types';
import routes from './routes';
import navs from './navs';
import { User } from '@shared/types';

let filteredRoutes: RouteItem[];
let filteredRouteMap: Record<string, RouteItem>;

const useRoutes = (user: User): RouteItem[] => {
    filteredRoutes = [];
    filteredRouteMap = {};

    const checkHasRole = (route: RouteItem): boolean => {
        if (user.roles && user.roles.length > 0 && route.roles && route.roles.length > 0) {
            for (let role of user.roles) {
                if (route.roles.includes(role)) {
                    return true;
                }
            }
            return false;
        }
        return true;
    }

    for (let route of routes) {
        let hasRole = checkHasRole(route);
        if (hasRole) {
            filteredRoutes.push(route);
            if (route.path) filteredRouteMap[route.path] = route;
        }
    }

    return filteredRoutes;
}

const useNavs = (user: User): NavItem[] => {

    if (!filteredRoutes) filteredRoutes = useRoutes(user);

    let originalNavs = navs;

    const process = (navs: NavItem[]): NavItem[] => {
        const newNavs: NavItem[] = [];
        for (let nav of navs) {
            const newNav: NavItem = {...nav};
            if (newNav.children) {
                const newChildren = process(newNav.children);
                if (newChildren.length < 1) {
                    newNav.children = undefined;
                } else {
                    newNav.children = newChildren;
                }
            }
            if (!newNav.url && !newNav.children) {
                newNav.hidden = true;
            } 
            if (newNav.url) {
                if (!filteredRouteMap[newNav.url]) {
                    continue;
                }
            }
            newNavs.push(newNav);
        }
        return newNavs;
    }

    return process(originalNavs);
}

export type RoutesProvider = {
    useRoutes: (user: User) => RouteItem[];
    useNavs: (user: User) => NavItem[];
};

const routesProvider: RoutesProvider = {
    useRoutes,
    useNavs,
};

export default routesProvider;
